﻿using System;
using System.Net;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Fdd.Aspen.Services.Web;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using Fdd.Aspen.Services.Web.PresentationModel;
using System.ServiceModel.DomainServices.Client;
using System.Diagnostics.Contracts;

namespace Fdd.Aspen.Client.ViewModels.DataChannels
{
    [Export(typeof(IListMemberViewModelDataChannel))]
    public class ListMemberViewModelDataChannel : IListMemberViewModelDataChannel
    {
        MemberDomainContext _memberDomainContext = new MemberDomainContext();


        public void GetAllMembersAsync(Action<DataChannelLoadOperation<IEnumerable<MemberPM>>> getAllMembersCompletedCallBack)
        {
            Contract.Requires(getAllMembersCompletedCallBack != null);

            _memberDomainContext.Load<MemberPM>(
                            _memberDomainContext.GetMembersQuery(),
                            loadOperation =>
                            {
                                getAllMembersCompletedCallBack(CreateDataChannelLoadOperation(loadOperation));
                            }
                            , null);
        }


        public void Save(Action<DataChannelSaveOperation> saveCompletedCallBack)
        {
            Contract.Requires(saveCompletedCallBack != null);

            _memberDomainContext.SubmitChanges(
                            submitOperation =>
                            {
                                saveCompletedCallBack(CreateDataChannelSaveOperation(submitOperation));
                            },
                            null);
        }


        public void AddMember(MemberPM member)
        {
            Contract.Requires(member != null);
            Contract.Requires(_memberDomainContext.MemberPMs.Count > 0);
            Contract.Ensures(_memberDomainContext.MemberPMs.Contains(member));

            _memberDomainContext.MemberPMs.Add(member);
        }


        public void RemoveMember(MemberPM member)
        {
            Contract.Requires(member != null);
            Contract.Ensures(!_memberDomainContext.MemberPMs.Contains(member));

            _memberDomainContext.MemberPMs.Remove(member);
        }


        public IEnumerable<MemberPM> LoadedMembers
        {
            get { return _memberDomainContext.MemberPMs; }
        }


        private static DataChannelSaveOperation CreateDataChannelSaveOperation(SubmitOperation submitOperation)
        {
            var saveOperation = new DataChannelSaveOperation();

            if (submitOperation.HasError)
            {
                saveOperation.Error = submitOperation.Error;
                submitOperation.MarkErrorAsHandled();
            }
            return saveOperation;
        }


        private static DataChannelLoadOperation<IEnumerable<MemberPM>> CreateDataChannelLoadOperation(
                                                                            LoadOperation<MemberPM> loadOperation)
        {
            var dataLoadOpearion = new DataChannelLoadOperation<IEnumerable<MemberPM>>();

            if (loadOperation.HasError)
            {
                dataLoadOpearion.Error = loadOperation.Error;
                loadOperation.MarkErrorAsHandled();
            }
            else
                dataLoadOpearion.Result = loadOperation.Entities;

            return dataLoadOpearion;
        }
    }
}
